package guiservice.server.controls;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.swing.JPanel;

@Log4j
public abstract class Control implements guiservice.common.controls.Control{

    @Getter
    protected final long id;
    @Getter
    protected final long owner;
    @Getter
    private String controlType;
    @Getter
    @Setter
    protected int xShift = 0;
    @Getter
    @Setter
    protected int yShift = 10;

    protected ConcurrentLinkedQueue updatesMassages;

    protected Control(long id, long ownerId, String className) {
        this.id = id;
        this.owner = ownerId;
        this.controlType = className;
    }

    public void setSize(int width, int height) {
        log.debug(String.format("Set size (%d, %d)", width, height));
        getComponent().setSize(width, height);
    }

    public void setPoint(int x, int y) {
        getComponent().setLocation(x, y);
    }

    public int getX() {
        return getComponent().getX();
    }

    public int getY() {
        return getComponent().getY();
    }

    public int getWidth() {
        return getComponent().getWidth();
    }

    public int getHeight() {
        return getComponent().getHeight();
    }

    public int getBackGround() {
        return getComponent().getBackground().getRGB();
    }

    public void setBackGround(int color) {
        getComponent().setBackground(new Color(color));
    }

    public void draw(Graphics g, JPanel board) {
        Graphics myGraphics = getGraphics();
        int x = getX(), y = getY(), width = getWidth(), height = getHeight();
        if (myGraphics != null) {
            myGraphics.setColor(new Color(getBackGround()));
            myGraphics.fillRect(x, y, width, height);
            Component myComponent = getComponent();
            myComponent.paint(myGraphics);
            getImage().flush();
            g.drawImage(getImage(), x, y, board);
        } else {
            log.debug(String.format("Size (%d, %d)", width, height));
        }
    }

    protected abstract Component getComponent();

    protected Image loadImage(String name) {
        Image result = null;
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            URL path = loader.getResource(name);
            log.debug(path);
            result = Toolkit.getDefaultToolkit().createImage(path);
        } catch (Exception e) {
            log.error("Error occurred while loading image ", e);
        } finally {
            return result;
        }
    }

    public boolean isContainer() {
        return false;
    }

    protected BufferedImage image;

    public Graphics getGraphics() {
        if (image == null) {
            if (getWidth() != 0 && getHeight() != 0) {
                log.debug(getWidth() + " " + getHeight());
                image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
            } else {
                return null;
            }
        }
        Graphics graphics = image.getGraphics();
        graphics.setColor(new Color(getBackGround()));
        graphics.fillRect(0, 0, getWidth(), getHeight());
        image.flush();
        return graphics;
    }

    public Image getImage() {
        return image;
    }

    public boolean contains(int x, int y) {
        int thisX = getX();
        int thisY = getY();
        return x <= thisX + getWidth() && x >= thisX && y <= thisY + getHeight() && y >= thisY;
    }

}

